(library (model)
  (export scm->vocabulary
          make-vocabulary
          vocabulary?
          vocabulary-metadata
          vocabulary-words
          vocabulary-shuffle
          vocabulary-filter)
  (import (except (rnrs base) vector-for-each)
          (only (guile)
                lambda* λ
                display
                simple-format
                write-char)
          (only (srfi srfi-9 gnu)
                set-record-type-printer!)
          (srfi srfi-43)
          (ice-9 ports)
          (ice-9 pretty-print)
          (json)
          (vector-utils)
          (only (words) filter-vocabulary-words))

  (define-json-type vocabulary
    (metadata)
    (words))

  (set-record-type-printer!
   vocabulary
   (lambda (record port)
     (display "<vocabulary:\n" port)
     (display
      (with-output-to-string
        (λ ()
          (pretty-print (vocabulary-metadata record)
                        #:width 80
                        #:display? #t)))
      port)
     (vector-for-each (λ (ind word)
                       (display
                        (with-output-to-string
                          (λ ()
                            (pretty-print word #:width 80 #:display? #t)))
                        port))
                     (vocabulary-words record))
     (display ">\n" port)))

  (define vocabulary-shuffle
    (λ (vocabulary)
      (make-vocabulary
       (vocabulary-metadata vocabulary)
       (vector-shuffle (vocabulary-words vocabulary)))))

  (define vocabulary-filter
    (λ (vocabulary . word-filters)
      "Take a VOCABULARY and any number of WORD-FILTERS. A
word-filter is a function, which filters a vector of words."
      (make-vocabulary
       (vocabulary-metadata vocabulary)
       (apply filter-vocabulary-words
              (vocabulary-words vocabulary)
              word-filters)))))
